using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
namespace Circus.CodeEditor.Serialization
{
	public class RtfExport : FmtExport
	{
		private class ColorComparer : IComparer<DictionaryEntry>
		{
			public int Compare(DictionaryEntry x, DictionaryEntry y)
			{
				return (int)x.Value - (int)y.Value;
			}
		}
		private const string rtfHeader = "{\\rtf1\\ansi ";
		private const string rtfGroupBegin = "{";
		private const string rtfGroupEnd = "}";
		private const string rtfFontTbl = "\\fonttbl ";
		private const string rtfColorTbl = "\\colortbl ";
		private const string rtfF1 = "\\f1 ";
		private const string rtfSize = "\\fs";
		private const string rtfLine = "\\line";
		private const string rtfCf = "\\cf";
		private const string rtfHighlight = "\\highlight";
		private const string rtfB = "\\b";
		private const string rtfI = "\\i";
		private const string rtfUl = "\\ul";
		private const string rtfStrike = "\\strike";
		private const string rtfB0 = "\\b0";
		private const string rtfI0 = "\\i0";
		private const string rtfUlnone = "\\ulnone";
		private const string rtfStrike0 = "\\strike0";
		private const string rtfTab = "\\tab";
		private const string rtfRed = "\\red";
		private const string rtfGreen = "\\green";
		private const string rtfBlue = "\\blue";
		private StringBuilder sBuilder;
		private StringBuilder rBuilder;
		private Hashtable colorTable;
		private bool needSpace;
		private void WriteString(string str)
		{
			if (str != string.Empty)
			{
				if (this.needSpace)
				{
					this.sBuilder.Append(' ');
				}
				this.needSpace = false;
				this.sBuilder.Append(str);
			}
		}
		private void WriteString(string str, bool newLine)
		{
			this.WriteString(str);
			if (newLine)
			{
				this.sBuilder.Append("\r\n");
				this.needSpace = false;
			}
		}
		private void WriteTag(string tag)
		{
			this.sBuilder.Append(tag);
			this.needSpace = true;
		}
		private int AddColor(Color color)
		{
			object obj = this.colorTable[color];
			int result;
			if (obj != null)
			{
				result = (int)obj;
			}
			else
			{
				int count = this.colorTable.Count;
				this.colorTable.Add(color, count);
				result = count;
			}
			return result;
		}
		private void WriteHeader()
		{
			this.writer.WriteLine("{\\rtf1\\ansi ");
		}
		private void WriteFontTable()
		{
			this.writer.Write("{\\fonttbl ");
			if (this.edit != null)
			{
				this.writer.Write("{\\f1 " + this.edit.Font.Name + ";}");
			}
			this.writer.WriteLine("}");
		}
		private void WriteColorTable()
		{
			if (this.colorTable.Count > 0)
			{
				List<DictionaryEntry> list = new List<DictionaryEntry>();
				this.writer.Write("{\\colortbl ");
				IDictionaryEnumerator enumerator = this.colorTable.GetEnumerator();
				enumerator.Reset();
				while (enumerator.MoveNext())
				{
					list.Add(enumerator.Entry);
				}
				list.Sort(new RtfExport.ColorComparer());
				foreach (DictionaryEntry current in list)
				{
					this.writer.Write(this.ColorToRtf((Color)current.Key) + ";");
				}
				this.writer.WriteLine("}");
			}
		}
		private string StringToRtf(string str, ref bool firstTab, ref bool lastTab)
		{
			string result;
			if (str == string.Empty || str == null)
			{
				result = str;
			}
			else
			{
				this.rBuilder.Length = 0;
				firstTab = (str[0] == '\t');
				lastTab = false;
				for (int i = 0; i < str.Length; i++)
				{
					char c = str[i];
					char c2 = c;
					if (c2 != '\t')
					{
						if (c2 != '\\')
						{
							switch (c2)
							{
							case '{':
							case '}':
								goto IL_7C;
							}
							if (lastTab)
							{
								this.rBuilder.Append(' ');
							}
							lastTab = false;
							if (c > '\u007f')
							{
								this.rBuilder.Append("\\u" + (int)c + "?");
							}
							else
							{
								this.rBuilder.Append(c);
							}
							goto IL_112;
						}
						IL_7C:
						lastTab = false;
						this.rBuilder.Append("\\" + c);
					}
					else
					{
						lastTab = true;
						this.rBuilder.Append("\\tab");
					}
					IL_112:;
				}
				result = this.rBuilder.ToString();
			}
			return result;
		}
		protected string ColorToRtf(Color color)
		{
			return string.Concat(new string[]
			{
				"\\red",
				color.R.ToString(),
				"\\green",
				color.G.ToString(),
				"\\blue",
				color.B.ToString()
			});
		}
		protected override void WriteForeColor(Color foreColor)
		{
			this.WriteTag("\\cf" + this.AddColor(foreColor));
		}
		protected override void WriteBackColor(Color backColor)
		{
			this.WriteTag("\\highlight" + this.AddColor(backColor));
		}
		protected override void RemoveFontStyle(FontStyle style)
		{
			switch (style)
			{
			case FontStyle.Bold:
				this.WriteTag("\\b0");
				break;
			case FontStyle.Italic:
				this.WriteTag("\\i0");
				break;
			case FontStyle.Bold | FontStyle.Italic:
				break;
			case FontStyle.Underline:
				this.WriteTag("\\ulnone");
				break;
			default:
				if (style == FontStyle.Strikeout)
				{
					this.WriteTag("\\strike0");
				}
				break;
			}
		}
		protected override void AddFontStyle(FontStyle style)
		{
			switch (style)
			{
			case FontStyle.Bold:
				this.WriteTag("\\b");
				break;
			case FontStyle.Italic:
				this.WriteTag("\\i");
				break;
			case FontStyle.Bold | FontStyle.Italic:
				break;
			case FontStyle.Underline:
				this.WriteTag("\\ul");
				break;
			default:
				if (style == FontStyle.Strikeout)
				{
					this.WriteTag("\\strike");
				}
				break;
			}
		}
		protected override void StartLine()
		{
			if (!this.firstLine)
			{
				this.WriteString(string.Empty, true);
				this.WriteTag("\\line");
			}
		}
		protected override void WriteText(int pos, string text)
		{
			bool flag = false;
			bool flag2 = false;
			string str = this.StringToRtf(text, ref flag, ref flag2);
			if (flag)
			{
				this.needSpace = false;
			}
			this.WriteString(str);
			if (flag2)
			{
				this.needSpace = true;
			}
		}
		public RtfExport()
		{
			this.colorTable = new Hashtable();
			this.sBuilder = new StringBuilder();
			this.rBuilder = new StringBuilder();
		}
		public override void BeginWrite(TextWriter writer, object userData)
		{
			base.BeginWrite(writer, userData);
			this.AddColor(this.foreColor);
		}
		public override void EndWrite()
		{
			this.WriteHeader();
			this.WriteFontTable();
			this.WriteColorTable();
			this.writer.Write("\\f1 ");
			if (this.edit != null)
			{
				this.writer.Write("\\fs" + ((int)this.edit.Font.Size * 2).ToString(), ' ');
			}
			this.writer.Write(this.sBuilder.ToString());
			this.writer.Write("}");
		}
	}
}
